import { Inject, Middleware, httpError, Config } from '@midwayjs/core';
import { NextFunction, Context } from '@midwayjs/koa';
import { JwtService } from '@midwayjs/jwt';
// import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager'; // Redis缓存相关依赖已注释

@Middleware()
export class JwtMiddleware {
    @Inject()
    jwtService: JwtService;
    // @InjectClient(CachingFactory, 'redis')
    // cache: MidwayCache; // Redis缓存客户端已注释，如需启用请取消注释
    @Config('jwtConfig') // 动态注入配置
    jwtConfig: { secret: string; expiresIn: string | number };
    resolve() {
        return async (ctx: Context, next: NextFunction) => {
            // 判断下有没有校验信息
            if (!ctx.headers['authorization']) {
                throw new httpError.UnauthorizedError('');
            }
            const parts = ctx.headers['authorization'].split(' ');
            if (parts.length !== 2 || parts[0] !== 'Bearer') {
                throw new httpError.UnauthorizedError('');
            }
            const [scheme, token] = parts;
            if (/^Bearer$/i.test(scheme)) {
                try {
                    const result = await this.jwtService.verify(
                        token,
                        this.jwtConfig.secret,
                        { complete: true }
                    );
                    if (typeof result === 'string') {
                        throw new httpError.UnauthorizedError('无效的 token');
                    }
                    ctx.user = result.payload;
                    
                    // Redis缓存验证逻辑已注释 - 如需启用用户token缓存验证，请取消以下注释
                    // try {
                    //     const userId = ctx.user.userId;
                    //     const userIdCache = await this.cache.get(`user:${userId}`);
                    //     if (!userIdCache) {
                    //         throw new httpError.UnauthorizedError('Token 无效');
                    //     }
                    // } catch (err) {
                    //     throw new httpError.UnauthorizedError('Token 验证失败');
                    // }
                    
                    await next();
                } catch (err) {
                    throw new Error(err);
                }
            };
        };
    }
    public match(ctx: Context): boolean {
        // 需要忽略JWT验证的路由
        const ignoreRoutes = ['/api/auth/login', '/api/auth/register'];
        const ignore = ignoreRoutes.some(route => ctx.path === route);
        return !ignore; // 返回false表示不应用中间件，返回true表示应用中间件
    }
    public static getName(): string {
        return 'jwt';
    }
}
